﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Drawing.Drawing2D;
using System.Web.SessionState;

namespace SFast.Files
{
    //图片处理类库

    public static class MyPic
    {

        #region 生成缩略图
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径  Server.MapPath）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径  Server.MapPath）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式 "HW":指定高宽缩放（可能变形） ,
        ///                                     "AUTO" : 指定高宽,居中放入白底背景中 ,
        ///                                     "W":指定宽，高按比例,  
        ///                                     "H":指定高，宽按比例  
        ///                                     "Cut":指定高宽裁减（不变形） </param> 
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            MakeThumbnail(originalImagePath, thumbnailPath, width, height, mode, "", "");
        }
        #endregion

        #region 生成缩略图(带文字水印)
        /// <summary>
        /// 生成缩略图(带文字水印)
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径 Server.MapPath）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径 Server.MapPath）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式 "HW":指定高宽缩放（可能变形） ,
        ///                                     "AUTO" : 指定高宽,居中放入白底背景中 ,
        ///                                     "W":指定宽，高按比例,  
        ///                                     "H":指定高，宽按比例  
        ///                                     "Cut":指定高宽裁减（不变形） </param>  
        ///  <param name="watermarkText">文字水印路径（物理路径 Server.MapPath）</param>  
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode, string watermarkText)
        {
            MakeThumbnail(originalImagePath, thumbnailPath, width, height, mode, watermarkText, "");
        }
        #endregion

        #region 生成缩略图(带文字水印,图片水印)
        /// <summary>
        /// 生成缩略图(带文字水印,图片水印)
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径 Server.MapPath）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径 Server.MapPath）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式 "HW":指定高宽缩放（可能变形） ,
        ///                                     "AUTO" : 指定高宽底画板,按比例缩略图片居中放入白底背景底画板中 ,
        ///                                     "W":指定宽，高按比例,  
        ///                                     "H":指定高，宽按比例  
        ///                                     "Cut":指定高宽裁减（不变形） </param>  
        ///  <param name="watermarkText">文字水印</param>
        ///  <param name="watermarkImage">图片水印路径 (物理路径 Server.MapPath)</param>   
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode, string watermarkText, string watermarkImage)
        {
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalImagePath);

            //如果图片大小跟要缩小的图片相等 不执行缩小
            if (originalImage.Height != height && originalImage.Width != width)
            {
                int ToBoardWidth = width;  //画板宽度
                int ToBoardHeight = height; //画板高度
                int towidth = width;        //缩略图宽度
                int toheight = height;      //缩略图高度

                int x = 0;
                int y = 0;
                int xj = 0; //绘图时左上角起始x坐标
                int yk = 0; //绘图时左上角起始Y坐标
                int ow = originalImage.Width;  //图片真实宽度
                int oh = originalImage.Height; //图片真实高度

                #region  图片宽高比例处理
                switch (mode.ToUpper())
                {
                    case "HW"://指定高宽缩放（可能变形）                
                        break;
                    case "W"://指定宽，高按比例                    
                        toheight = originalImage.Height * width / originalImage.Width;
                        ToBoardHeight = toheight; //画板高度跟随缩略高相同
                        break;
                    case "H"://指定高，宽按比例
                        towidth = originalImage.Width * height / originalImage.Height;
                        ToBoardWidth = towidth; //画板宽度跟缩略宽相同
                        break;
                    case "Cut"://指定高宽裁减（不变形）                
                        if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                        {
                            oh = originalImage.Height;
                            ow = originalImage.Height * towidth / toheight;
                            y = 0;
                            x = (originalImage.Width - ow) / 2;
                        }
                        else
                        {
                            ow = originalImage.Width;
                            oh = originalImage.Width * height / towidth;
                            x = 0;
                            y = (originalImage.Height - oh) / 2;
                        }
                        break;
                    case "AUTO"://指定高宽,居中放入白底背景中 
                        //先按宽度压缩
                        toheight = originalImage.Height * width / originalImage.Width;
                        //如果按宽度压缩后的高度高于理想高度,按高度压缩
                        if (toheight > height)
                        {
                            towidth = originalImage.Width * height / originalImage.Height;
                            toheight = height;
                        }
                        else
                        {
                            towidth = width;
                        }
                        xj = (width - towidth) / 2;
                        yk = (height - toheight) / 2;
                        break;
                    default:
                        break;
                }
                #endregion

                #region  画图

                //新建一个bmp图片
                System.Drawing.Image bitmap = new System.Drawing.Bitmap(ToBoardWidth, ToBoardHeight);

                //新建一个画板
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

                //设置高质量插值法
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                //高质量符合度
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                //设置高质量,低速度呈现平滑程度
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

                //清空画布并以透明背景色填充
                g.Clear(System.Drawing.Color.White);

                //在指定位置并且按指定大小绘制原图片的指定部分
                g.DrawImage(originalImage, new System.Drawing.Rectangle(xj, yk, towidth, toheight),
                    new System.Drawing.Rectangle(x, y, ow, oh),
                    System.Drawing.GraphicsUnit.Pixel);

                #region 水印处理
                //文字水印
                if (watermarkText != "")
                {

                    System.Drawing.Font fontWater = new Font("楷体", 10);

                    System.Drawing.Brush brushWater = new SolidBrush(Color.Black);

                    g.DrawString(watermarkText, fontWater, brushWater, 10, 10);

                }



                //透明图片水印  

                if (watermarkImage != "")
                {

                    if (File.Exists(watermarkImage))
                    {

                        //获取水印图片  

                        using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
                        {

                            //水印绘制条件：原始图片宽高均大于或等于水印图片  

                            if (originalImage.Width >= wrImage.Width && originalImage.Height >= wrImage.Height)
                            {

                                //透明属性  

                                ImageAttributes imgAttributes = new ImageAttributes();

                                ColorMap colorMap = new ColorMap();

                                colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);

                                colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

                                ColorMap[] remapTable = { colorMap };

                                imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);



                                float[][] colorMatrixElements = {   

                                   new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},  

                                   new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},  

                                   new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},  

                                   new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},//透明度:0.5  

                                   new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}  

                                };



                                ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);

                                imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                                g.DrawImage(wrImage, new Rectangle(originalImage.Width - wrImage.Width, originalImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes);


                            }

                            wrImage.Dispose();

                        }

                    }

                }
                #endregion


                #endregion

                #region 图片处理保存在制定目录下 , 并释放所有资源对象
                try
                {
                    //判断如果文件存在,删除源文件
                    if (File.Exists(thumbnailPath))
                    {
                        originalImage.Dispose();
                        File.Delete(thumbnailPath);
                    }
                    //以jpg格式保存缩略图
                    bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
                catch (System.Exception e)
                {
                    throw e;
                }
                finally
                {

                    bitmap.Dispose();
                    g.Dispose();
                }
                #endregion
            }
            else
            {
                originalImage.Dispose();
            }
        }
        #endregion

        #region 获取随即数字

        #region 创建返回验证码，调用此函数程序将会终止，并返回图片
        /// <summary>
        /// 创建返回验证码，调用此函数程序将会终止，并返回图片
        /// </summary>
        /// <param name="type">1：汉字验证码 2：数字验证码 3：数字和英文混合验证码</param>
        public static void CreateCode(int type)
        {
            switch (type)
            {
                case 1:
                    //gif = stxt(10);
                    HttpContext.Current.Session["MyCommon_yzm_code"] = stxt(10);
                    break;
                case 2:
                    //gif = GetRandomint(4);
                    HttpContext.Current.Session["MyCommon_yzm_code"] = GetRandomint(4);
                    break;
                case 3:
                    //gif = CreateRandomCode(4);
                    HttpContext.Current.Session["MyCommon_yzm_code"] = CreateRandomCode(4);
                    break;
                default:
                    //gif = CreateRandomCode(4);
                    HttpContext.Current.Session["MyCommon_yzm_code"] = CreateRandomCode(4);
                    break;
            }
            CreateImage(HttpContext.Current.Session["MyCommon_yzm_code"].ToString());
        }
        #endregion

        public static String GetCodeStr()
        {
            HttpSessionState session = HttpContext.Current.Session;
            if (HttpContext.Current.Session["MyCommon_yzm_code"] == null)
            {
                return "";
            }
            else
            {
                return HttpContext.Current.Session["MyCommon_yzm_code"].ToString();
            }

        }


        private static string stxt(int num)
        {
            Encoding gb = Encoding.GetEncoding("gb2312");

            //调用函数产生10个随机中文汉字编码   
            object[] bytes = CreateRegionCode(num);
            string strtxt = "";

            //根据汉字编码的字节数组解码出中文汉字   
            for (int i = 0; i < num; i++)
            {
                strtxt += gb.GetString((byte[])Convert.ChangeType(bytes[i], typeof(byte[])));
            }
            return strtxt;
        }

        #region 创建有文字的图片
        /// <summary>
        /// 创建有文字的图片
        /// </summary>
        /// <param name="checkCode"></param>
        private static void CreateImage(string checkCode)
        {
            if (checkCode == null || checkCode.Trim() == String.Empty)
                return;
            int iWordWidth = 17;
            int iImageWidth = checkCode.Length * iWordWidth;
            Bitmap image = new Bitmap(iImageWidth, 25);
            Graphics g = Graphics.FromImage(image);
            try
            {
                //生成随机生成器 
                Random random = new Random();
                //清空图片背景色 
                g.Clear(Color.White);

                //画图片的背景噪音点
                for (int i = 0; i < 20; i++)
                {
                    int x1 = random.Next(image.Width);
                    int x2 = random.Next(image.Width);
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);
                    g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
                }

                //画图片的背景噪音线 
                for (int i = 0; i < 2; i++)
                {
                    int x1 = 0;
                    int x2 = image.Width;
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);
                    if (i == 0)
                    {
                        g.DrawLine(new Pen(Color.Gray, 2), x1, y1, x2, y2);
                    }

                }


                for (int i = 0; i < checkCode.Length; i++)
                {

                    string Code = checkCode[i].ToString();
                    int xLeft = iWordWidth * (i);
                    random = new Random(xLeft);
                    int iSeed = DateTime.Now.Millisecond;
                    int iValue = random.Next(iSeed) % 4;
                    if (iValue == 0)
                    {
                        Font font = new Font("Arial", 13, (FontStyle.Bold | System.Drawing.FontStyle.Italic));
                        Rectangle rc = new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush = new LinearGradientBrush(rc, Color.Blue, Color.Red, 1.5f, true);
                        g.DrawString(Code, font, brush, xLeft, 2);
                    }
                    else if (iValue == 1)
                    {
                        Font font = new System.Drawing.Font("楷体", 13, (FontStyle.Bold));
                        Rectangle rc = new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush = new LinearGradientBrush(rc, Color.Blue, Color.DarkRed, 1.3f, true);
                        g.DrawString(Code, font, brush, xLeft, 2);
                    }
                    else if (iValue == 2)
                    {
                        Font font = new System.Drawing.Font("宋体", 13, (System.Drawing.FontStyle.Bold));
                        Rectangle rc = new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush = new LinearGradientBrush(rc, Color.Green, Color.Blue, 1.2f, true);
                        g.DrawString(Code, font, brush, xLeft, 2);
                    }
                    else if (iValue == 3)
                    {
                        Font font = new System.Drawing.Font("黑体", 13, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Bold));
                        Rectangle rc = new Rectangle(xLeft, 0, iWordWidth, image.Height);
                        LinearGradientBrush brush = new LinearGradientBrush(rc, Color.Blue, Color.Green, 1.8f, true);
                        g.DrawString(Code, font, brush, xLeft, 2);
                    }
                }
                //////画图片的前景噪音点 
                //for (int i = 0; i < 8; i++)
                //{
                //    int x = random.Next(image.Width);
                //    int y = random.Next(image.Height);
                //    image.SetPixel(x, y, Color.FromArgb(random.Next()));
                //}
                //画图片的边框线 
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                HttpContext.Current.Response.ClearContent();
                HttpContext.Current.Response.ContentType = "image/Jpeg";
                HttpContext.Current.Response.BinaryWrite(ms.ToArray());
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
        #endregion

        #region 这个是使用字母,数字混合
        /// <summary>  
        /// 这个是使用字母,数字混合  
        /// </summary>  
        /// <param name="VcodeNum"></param>  
        /// <returns></returns>  
        private static string CreateRandomCode(int codeCount)
        {
            string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
            string[] allCharArray = allChar.Split(',');
            string randomCode = "";
            int temp = -1;
            Random rand = new Random();
            for (int i = 0; i < codeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(61);
                if (temp == t)
                {
                    return CreateRandomCode(codeCount);
                }
                temp = t;
                randomCode += allCharArray[t];
            }
            return randomCode;
        }
        #endregion


        /// <summary>
        /// 此函数在汉字编码范围内随机创建含两个元素的十六进制字节数组，每个字节数组代表一个汉字，并将  
        /// 四个字节数组存储在object数组中。  
        /// </summary>
        /// <param name="strlength">代表需要产生的汉字个数</param>
        /// <returns></returns>
        private static object[] CreateRegionCode(int strlength)
        {
            //定义一个字符串数组储存汉字编码的组成元素   
            string[] rBase = new String[16] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
            Random rnd = new Random();
            //定义一个object数组用来   
            object[] bytes = new object[strlength];


            /*每循环一次产生一个含两个元素的十六进制字节数组，并将其放入bject数组中  
            每个汉字有四个区位码组成  
            区位码第1位和区位码第2位作为字节数组第一个元素  
            区位码第3位和区位码第4位作为字节数组第二个元素  
            */
            for (int i = 0; i < strlength; i++)
            {
                //区位码第1位   
                int r1 = rnd.Next(11, 14);
                string str_r1 = rBase[r1].Trim();

                //区位码第2位   
                rnd = new Random(r1 * unchecked((int)DateTime.Now.Ticks) + i);//更换随机数发生器的种子避免产生重复值   
                int r2;
                if (r1 == 13)
                {
                    r2 = rnd.Next(0, 7);
                }
                else
                {
                    r2 = rnd.Next(0, 16);
                }
                string str_r2 = rBase[r2].Trim();

                //区位码第3位   
                rnd = new Random(r2 * unchecked((int)DateTime.Now.Ticks) + i);
                int r3 = rnd.Next(10, 16);
                string str_r3 = rBase[r3].Trim();

                //区位码第4位   
                rnd = new Random(r3 * unchecked((int)DateTime.Now.Ticks) + i);
                int r4;
                if (r3 == 10)
                {
                    r4 = rnd.Next(1, 16);
                }
                else if (r3 == 15)
                {
                    r4 = rnd.Next(0, 15);
                }
                else
                {
                    r4 = rnd.Next(0, 16);
                }
                string str_r4 = rBase[r4].Trim();

                //定义两个字节变量存储产生的随机汉字区位码   
                byte byte1 = Convert.ToByte(str_r1 + str_r2, 16);
                byte byte2 = Convert.ToByte(str_r3 + str_r4, 16);
                //将两个字节变量存储在字节数组中   
                byte[] str_r = new byte[] { byte1, byte2 };

                //将产生的一个汉字的字节数组放入object数组中   
                bytes.SetValue(str_r, i);
            }
            return bytes;
        }


        /// <summary>
        /// 获取随即数字
        /// </summary>
        /// <param name="codeCount"></param>
        /// <returns></returns>
        private static String GetRandomint(int codeCount)
        {
            Random random = new Random();
            string min = "";
            string max = "";
            for (int i = 0; i < codeCount; i++)
            {
                min += "1";
                max += "9";
            }
            return (random.Next(Convert.ToInt32(min), Convert.ToInt32(max)).ToString());
        }
        #endregion
    }
}
